package cn.jinjimi.base.util;

import android.app.Activity;
import android.app.ActivityManager;
import android.app.Application;
import android.app.KeyguardManager;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.net.Uri;
import android.os.Build;
import android.os.Environment;
import android.os.Handler;
import android.os.StatFs;
import android.telephony.TelephonyManager;
import android.text.TextUtils;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.Display;
import android.view.View;
import android.view.Window;
import android.view.WindowManager;
import android.view.inputmethod.InputMethodManager;

import java.io.File;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.List;


/**
 * Android 工具类
 * <p/>
 * Created by zhihui_chen on 14-8-4.
 */
public class AndroidUtils {
    private static final String TAG = AndroidUtils.class.getName();

    private static int windowWidth = -1;
    private static int windowHeight = -1;
    private static int statusBarHeight = -1;

    private static Application mApplication;

    public static void init(Application app) {
        mApplication = app;
    }

    public static int getWindowWidth(Context context) {
        if (windowWidth == -1) {
            DisplayMetrics dm = context.getResources().getDisplayMetrics();
            windowWidth = dm.widthPixels;
        }

        return windowWidth;
    }

    public static int getWindowHeight(Context context) {
        if (windowHeight == -1) {
            DisplayMetrics dm = context.getResources().getDisplayMetrics();
            windowHeight = dm.heightPixels;
        }

        return windowHeight;
    }

    public static int[] getScreeSize() {
        if (mApplication == null)
            throw new RuntimeException("You should invoke init() first or use getScreeSize(context)");
        return getScreeSize(mApplication);
    }

    public static int[] getScreeSize(Context ctx) {
        WindowManager wmgr = (WindowManager) ctx.getSystemService(Context.WINDOW_SERVICE);

        int[] result = new int[2];
        result[0] = -1;
        result[1] = -1;

        if (wmgr != null) {
            DisplayMetrics displayMetrics = new DisplayMetrics();
            wmgr.getDefaultDisplay().getMetrics(displayMetrics);

            result[0] = displayMetrics.widthPixels;
            result[1] = displayMetrics.heightPixels;
            return result;
        }
        return result;
    }

    public static int getStatusBarHeight(Context context) {
        if (statusBarHeight < 0) {
            Class<?> c = null;
            Object obj = null;
            Field field = null;
            try {
                c = Class.forName("com.android.internal.R$dimen");
                obj = c.newInstance();
                field = c.getField("status_bar_height");
                int x = Integer.parseInt(field.get(obj).toString());
                statusBarHeight = context.getResources().getDimensionPixelSize(x);
            } catch (Exception e1) {

            }
        }

        return statusBarHeight;
    }

    public static int getStatusBarHeight() {
        if (mApplication == null)
            throw new RuntimeException("You should invoke init() first or use getStatusBarHeight(context)");
        return getStatusBarHeight(mApplication);
    }

    /**
     * 打开软键盘
     *
     * @param window
     */
    public static void showSoftKeyBoard(final Window window) {
        new Handler().postDelayed(new Runnable() {
            @Override
            public void run() {
                if (window.getCurrentFocus() != null) {
                    InputMethodManager inputManager = (InputMethodManager) window.getContext().getSystemService(Activity.INPUT_METHOD_SERVICE);
                    inputManager.showSoftInputFromInputMethod(window.getCurrentFocus().getWindowToken(), 0);
                }
            }
        }, 200);
    }

    public static void showSoftKeyBoard(final View v) {
        new Handler().postDelayed(new Runnable() {
            @Override
            public void run() {
                if (v != null) {
                    InputMethodManager imm = (InputMethodManager) v.getContext().getSystemService(Context.INPUT_METHOD_SERVICE);
                    imm.showSoftInput(v, InputMethodManager.SHOW_IMPLICIT);
                }
            }
        }, 200);
    }

    /**
     * 关闭软键盘
     *
     * @param window
     */
    public static void hideSoftKeyBoard(final Window window) {
        new Handler().postDelayed(new Runnable() {
            @Override
            public void run() {
                if (window.getCurrentFocus() != null) {
                    InputMethodManager inputManager = (InputMethodManager) window.getContext().getSystemService(Activity.INPUT_METHOD_SERVICE);
                    inputManager.hideSoftInputFromWindow(window.getCurrentFocus().getWindowToken(), 0);
                }
            }
        }, 200);
    }

    public static void hideSoftKeyBoard(final Context ctx, final View v) {
        new Handler().postDelayed(new Runnable() {
            @Override
            public void run() {
                InputMethodManager imm = (InputMethodManager) ctx.getSystemService(Context.INPUT_METHOD_SERVICE);
                imm.hideSoftInputFromWindow(v.getWindowToken(), 0);
            }
        }, 200);
    }

    /**
     * 安装apk
     *
     * @param apkFilePath
     */
    public static void installApk(Context ctx, String apkFilePath) {
        File apkfile = new File(apkFilePath);
        if (!apkfile.exists()) {
            ToastUtils.toastMessage(ctx, "安装主程序失败，找不到主程序文件，请尝试重新更新。");
            return;
        }
        Log.d(TAG, "install apk: " + apkfile.getPath());
        Intent i = new Intent(Intent.ACTION_VIEW);
        i.setDataAndType(Uri.parse("file://" + apkfile.toString()),
                "application/vnd.android.package-archive");
        i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        ctx.startActivity(i);
    }


    /**
     * 获取App安装包信息
     *
     * @return
     */
    public PackageInfo getPackageInfo(Context context) {
        PackageInfo info = null;
        try {
            info = context.getPackageManager().getPackageInfo(context.getPackageName(), 0);
        } catch (PackageManager.NameNotFoundException e) {
            Log.e(TAG, "程序包名无法找到", e);
        }
        if (info == null)
            info = new PackageInfo();
        return info;
    }

    /**
     * 获取metaData信息
     */
    public static String getMetaData(Context context, String key) {
        String metaData = "";
        try {
            ApplicationInfo appInfo = context.getPackageManager()
                    .getApplicationInfo(context.getPackageName(),
                            PackageManager.GET_META_DATA);
            metaData = appInfo.metaData.getString(key);
        } catch (PackageManager.NameNotFoundException e) {
            Log.e(TAG, "获取metaData信息", e);
        } catch (Exception e) {

        }
        return metaData;
    }

    /**
     * 获取当前程序版本名称
     */
    public static String getAppVersionName(Context context) {
        String versionName = "";
        try {
            // Get the package info
            PackageManager pm = context.getPackageManager();
            PackageInfo pi = pm.getPackageInfo(context.getPackageName(), 0);
            versionName = pi.versionName;
            if (TextUtils.isEmpty(versionName)) {
                return "";
            }
        } catch (PackageManager.NameNotFoundException e) {
            Log.e(TAG, "获取当前程序版本名称", e);
        } catch (Exception e) {

        }
        return versionName;
    }

    /**
     * 获取程序版本名称
     */
    public static String getAppVersionName(Context context, String packageName) {
        String versionName;
        try {
            // Get the package info
            PackageInfo pi = context.getPackageManager().getPackageInfo(packageName, 0);
            versionName = pi.versionName;
            if (TextUtils.isEmpty(versionName)) {
                return "";
            }
        } catch (PackageManager.NameNotFoundException e) {
            Log.d(TAG, "获取程序版本名称", e);
            return "";
        } catch (Exception e) {
            return "";
        }
        return versionName;
    }

    /**
     * 获取当前代码版本号
     */
    public static int getAppVersionCode(Context context) {
        int localVersion = 0;
        try {
            PackageManager pm = context.getPackageManager();
            PackageInfo pi = pm.getPackageInfo(context.getPackageName(), 0);
            localVersion = pi.versionCode;
        } catch (PackageManager.NameNotFoundException e) {
            Log.e(TAG, "获取当前代码版本号", e);
        } catch (Exception e) {

        }
        return localVersion;
    }

    /**
     * 比较两个app版本号，看是否是大版本跨度，提示更新
     *
     * @param targetVersion
     * @param baseVersion
     * @return true if targetVersion > baseVersion,only compare forward（1.9.0 > 1.8.0   1.9.1 < 1.9.0）
     * install
     * TODO int 比较位数
     */
    public static boolean isBigVersionUpdate(String targetVersion, String baseVersion) {
        if (StringUtils.isEmpty(targetVersion)) {
            return false;// empty target, return false
        }
        if (StringUtils.isEmpty(baseVersion)) {
            return true;// not install, return true
        }
        List<String> targetItems = StringUtils.stringToList(targetVersion, StringUtils.VERSION_SEPERATOR);
        List<String> baseItems = StringUtils.stringToList(baseVersion, StringUtils.VERSION_SEPERATOR);

        if (CollectionUtils.isEmpty(targetItems) || CollectionUtils.isEmpty(baseItems)) {
            return false;
        }

        final int targetSize = targetItems.size();
        final int baseSize = baseItems.size();

        for (int i = 0; i < 2; i++) { // 判断是否为大版本更新只判断前两位
            int targetV = (i >= targetSize) ? 0 : Integer.parseInt(targetItems.get(i));
            int baseV = (i >= baseSize) ? 0 : Integer.parseInt(baseItems.get(i));
            if (targetV > baseV) {
                return true;
            }
            if (targetV < baseV) {
                return false;
            }
        }
        return false;
    }

    /**
     * 比较两个版本号
     *
     * @param targetVersion
     * @param baseVersion
     * @return true if targetVersion > baseVersion（1.9 > 1.8.0   1.9.1 < 1.9.0）
     */
    public static boolean isBigVersion(String targetVersion, String baseVersion) {
        if (StringUtils.isEmpty(targetVersion)) {
            return false;// empty target, return false
        }
        if (StringUtils.isEmpty(baseVersion)) {
            return true;// not install, return true
        }
        List<String> targetItems = StringUtils.stringToList(targetVersion, StringUtils.VERSION_SEPERATOR);
        List<String> baseItems = StringUtils.stringToList(baseVersion, StringUtils.VERSION_SEPERATOR);

        if (CollectionUtils.isEmpty(targetItems) || CollectionUtils.isEmpty(baseItems)) {
            return false;
        }

        int targetSize = targetItems.size();
        int baseSize = baseItems.size();

        // 补全尾数，为下一步匹配做准备
        for (int i = 0; i < Math.abs(targetSize - baseSize); i++) {
            if (targetSize > baseSize)
                baseItems.add("0");
            else
                targetItems.add("0");
        }
        try {
            for (int i = 0, j = baseItems.size(); i < j; i++) {
                int targetV = Integer.parseInt(targetItems.get(i));
                int baseV = Integer.parseInt(baseItems.get(i));
                if (targetV > baseV) {
                    return true;
                }
                if (targetV < baseV) {
                    return false;
                }
            }
        } catch (Exception e) {

        }

        return false;
    }

    /**
     * 获取当前android手机型号
     */
    public static String getDriverModel() {
        String DeviceModel;
        DeviceModel = Build.MODEL;
        if (TextUtils.isEmpty(DeviceModel)) {
            return "";
        }
        return DeviceModel;
    }

    /**
     * 获取当前系统版本号
     */
    public static String getDriverVersionName() {
        String DeviceVersionName;
        DeviceVersionName = Build.VERSION.RELEASE;
        if (TextUtils.isEmpty(DeviceVersionName)) {
            return "";
        }
        return DeviceVersionName;
    }

    public static String getImei(Context context) {
        String imei = "";
        try {
            imei = ((TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE)).getDeviceId();
        } catch (Exception e) {

        }

        return imei;
    }

    /* 获取当前系统版本名称 */
    public static String getSystemVersionName() {
        return Build.VERSION.RELEASE;
    }

    /**
     * 是否锁屏状态
     *
     * @return
     */
    public static boolean isKeyguard() {
        if (mApplication == null)
            throw new RuntimeException("You should invoke init() first or use isKeyguard(context)");
        return isKeyguard(mApplication);
    }

    public static boolean isKeyguard(Context ctx) {

        KeyguardManager mKeyguardManager = (KeyguardManager) ctx.getSystemService(Context.KEYGUARD_SERVICE);

        return mKeyguardManager.inKeyguardRestrictedInputMode();
    }

    /**
     * 通知媒体库更新文件
     *
     * @param context
     * @param filePath 文件全路径
     */
    public static void scanFile(Context context, String filePath) {
        Intent scanIntent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
        scanIntent.setData(Uri.fromFile(new File(filePath)));
        context.sendBroadcast(scanIntent);
    }

    /**
     * 通知媒体库更新文件夹
     *
     * @param context
     * @param filePath 文件夹
     */
    public static void scanFiles(Context context, String filePath) {
        if (hasKitKat()) {
            Intent mediaScanIntent = new Intent(
                    Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
            Uri contentUri = Uri.fromFile(new File(filePath)); //out is your output file
            mediaScanIntent.setData(contentUri);
            context.sendBroadcast(mediaScanIntent);
        } else {
            Intent scanIntent = new Intent(Intent.ACTION_MEDIA_MOUNTED);
            scanIntent.setData(Uri.fromFile(new File(filePath)));
            context.sendBroadcast(scanIntent);
        }
    }

    /**
     * 调起手机拨打电话界面
     *
     * @param context
     * @param number
     */
    public static void call(Context context, String number) {
        Intent intent = new Intent();
        intent.setAction(Intent.ACTION_DIAL);
        intent.setData(Uri.parse("tel:" + number));
        context.startActivity(intent);
    }

    /**
     * 调起手机发送短信
     *
     * @param context
     * @param number
     * @param defaultContent
     */
    public static void sendMsg(Context context, String number, String defaultContent) {
        Intent intent = new Intent(Intent.ACTION_SENDTO, Uri.parse("smsto:" + number));
        intent.putExtra("sms_body", defaultContent);
        context.startActivity(intent);
    }

    public static boolean hasGingerbread() { /*2.3.1 API 9*/
        return Build.VERSION.SDK_INT >= Build.VERSION_CODES.GINGERBREAD;
    }

    public static boolean hasHoneycomb() {/*3.0.X  API 11*/
        return Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB;
    }

    public static boolean hasHoneycombMR1() {/*3.1.X  API 12*/
        return Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB_MR1;
    }

    public static boolean hasHoneycombMR2() {/*3.2 API 13*/
        return Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB_MR2;
    }

    public static boolean hasIceCreamSandwich() {/*4.0, 4.0.1, 4.0.2 API 14*/
        return Build.VERSION.SDK_INT > -Build.VERSION_CODES.ICE_CREAM_SANDWICH;
    }

    public static boolean hasJellyBean() {/*4.1, 4.1.1  API 16 */
        return Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN;
    }

    public static boolean hasKitKat() {/*4.4  API 19 */
        return Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT;
    }

    /**
     * 是否存在SD卡
     *
     * @return
     */
    public static boolean isExsitSDCard() {
        String storageState = Environment.getExternalStorageState();
        return storageState.equals(Environment.MEDIA_MOUNTED);
    }

    /**
     * 取得空闲SD卡空间大小
     *
     * @return MB
     */
    public static long getAvailaleSize() {
        File path = Environment.getExternalStorageDirectory(); // 取得sdcard文件路径
        StatFs stat = new StatFs(path.getPath());
        /* 获取block的SIZE */
        long blockSize = stat.getBlockSize();
        /* 空闲的Block的数量 */
        long availableBlocks = stat.getAvailableBlocks();
        /* 返回bit大小值 */
        return availableBlocks * blockSize / 1024 / 1024;
    }

    public static void collapseStatusBar(Context context) {
        try {
            Object statusBarManager = context.getSystemService("statusbar");
            Method collapse;
            if (Build.VERSION.SDK_INT <= 16) {
                collapse = statusBarManager.getClass().getMethod("collapse");
            } else {
                collapse = statusBarManager.getClass().getMethod("collapsePanels");
            }
            collapse.invoke(statusBarManager);
        } catch (Exception localException) {
            localException.printStackTrace();
        }
    }

    /**
     * 请求打开悬浮框权限
     *
     * @param aty
     */
    public static void requestDrawOverLays(Context aty) {
        try {
            if (!SettingsCompat.canDrawOverlays(aty)) {
                ToastUtils.toastMessage(aty, "开启悬浮框权限才能使用完整的功能");
                SettingsCompat.manageDrawOverlays(aty);
            }
        } catch (Exception e) {
        }
    }


    /**
     * 获取屏幕尺寸，但是不包括虚拟功能高度
     *
     * @return
     */
    public static int getNoHasVirtualKey(Activity ctx) {
        int height = ctx.getWindowManager().getDefaultDisplay().getHeight();
        Log.e(TAG, "getNoHasVirtualKey: " + height);
        return height;
    }

    /**
     * 通过反射，获取包含虚拟键的整体屏幕高度
     *
     * @return
     */
    public static int getHasVirtualKey(Activity aty) {
        int dpi = 0;
        Display display = aty.getWindowManager().getDefaultDisplay();
        DisplayMetrics dm = new DisplayMetrics();
        @SuppressWarnings("rawtypes")
        Class c;
        try {
            c = Class.forName("android.view.Display");
            @SuppressWarnings("unchecked")
            Method method = c.getMethod("getRealMetrics", DisplayMetrics.class);
            method.invoke(display, dm);
            dpi = dm.heightPixels;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return dpi;
    }

    public static int getVirtualViewHigh(Activity aty) {
        return getHasVirtualKey(aty) - getNoHasVirtualKey(aty);
    }

    public static ComponentName getTopActivity(Context context) {
        ActivityManager am = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
        if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            List<ActivityManager.AppTask> tasks = am.getAppTasks();
            if (tasks != null && tasks.size() > 0) {
                return tasks.get(0).getTaskInfo().topActivity;
            }
        } else {
            List<ActivityManager.RunningTaskInfo> infos = am.getRunningTasks(1);
            if (infos != null && infos.size() > 0) {
                return infos.get(0).topActivity;
            }
        }

        return null;
    }
}
